#include "audiodecodetask.h"
#include <qDebug>
AudioDecodeTask::AudioDecodeTask(Receive_handler *pHandler):m_pHandler(pHandler)
{
    Dec_AudioCodec = avcodec_find_decoder(AV_CODEC_ID_AAC);

    if (!Dec_AudioCodec)
    {
        //qDebug(QString("p_avcodec_find_decoder执行失败:").append(QString::number((long)videoCodec)).toLocal8Bit().data());
        return  ;
    }

    Dec_AvContext = avcodec_alloc_context3(Dec_AudioCodec);
    if (!Dec_AvContext)
    {
            fprintf(stderr, "Could not allocate video codec context\n");
            exit(1);
    }

    Dec_AvContext->codec_id   = AV_CODEC_ID_AAC;//AV_CODEC_ID_AMR_NB
    Dec_AvContext->codec_type = AVMEDIA_TYPE_AUDIO;
    Dec_AvContext->sample_fmt = AV_SAMPLE_FMT_S16;  //16位
    Dec_AvContext->sample_rate= 8000;               //8000 采样
    Dec_AvContext->channel_layout=AV_CH_LAYOUT_MONO;//单声道
    Dec_AvContext->channels = 1;                    //单声道

    if (avcodec_open2(Dec_AvContext, Dec_AudioCodec, NULL) < 0)
    {
        qDebug(QString("Could not open codec").toLocal8Bit().data());
        //fprintf(stderr, "Could not open codec\n");
        return ;
    }

    pCacheFrame = avcodec_alloc_frame();

    //struct SwrContext *au_convert_ctx;
    out_buffer_size = av_samples_get_buffer_size(NULL, 1,1024,AV_SAMPLE_FMT_S16, 1);

    qDebug(QString("av_samples_get_buffer_size:").append(QString::number((long)out_buffer_size)).toLocal8Bit().data());
    qDebug(QString("channels_size1:").append(QString::number((long)Dec_AvContext->sample_fmt)).toLocal8Bit().data());
    qDebug(QString("channels_size2:").append(QString::number((long)AV_SAMPLE_FMT_S16)).toLocal8Bit().data());

    out_buffer = (uint8_t *)av_malloc(out_buffer_size * 2);

    au_convert_ctx = swr_alloc();
    au_convert_ctx=swr_alloc_set_opts(au_convert_ctx,AV_CH_LAYOUT_MONO, AV_SAMPLE_FMT_S16, 8000,
        av_get_default_channel_layout(Dec_AvContext->channels),Dec_AvContext->sample_fmt , Dec_AvContext->sample_rate,0, NULL);
    swr_init(au_convert_ctx);

    m_pack_num1 = 0;
    m_pack_num2 = 0;


    char aacFileName[100]={0};
    sprintf(aacFileName,"/sdcard/test6.pcm");//  /storage/sdcard0/new23.aac

    outfile = fopen(aacFileName, "wb");

}

AudioDecodeTask::~AudioDecodeTask()
{

    if(Dec_AvContext)
    {
       avcodec_close(Dec_AvContext);
    }
    if(pCacheFrame)
    {
         av_free(pCacheFrame);
         pCacheFrame = 0;
    }

    if(au_convert_ctx)
    {
        swr_free(&au_convert_ctx);
    }

    if(out_buffer)
    {
        av_free(out_buffer);
    }

    if(outfile)
        fclose(outfile);
}

int AudioDecodeTask::close()
{
    std::string str("");

    int nthread  =thr_count();

    for (int i =0 ;i<nthread ;i++)
        putq(str);

    wait();
    return 0;
}

bool AudioDecodeTask::receive_handler(char *data, int size)
{
    m_pack_num1 ++ ;
    //qDebug(QString("NetWorkImpl::RecvData size:").append(QString::number((long)size)).toLocal8Bit().data());
    putq(std::string(data,size));
    return true;
}

int AudioDecodeTask::svc()
{
    std::string str ="";

    AVPacket *packet=(AVPacket *)malloc(sizeof(AVPacket));

    av_init_packet(packet);

    int ret, got_picture;

     while(getq(str))
     {
        if (str=="")
            break;

        m_pack_num2 ++;

        packet->data =  (uint8_t *)(const_cast<char *>(str.data()));//,str.length()
        packet->size = str.length();

        got_picture = 0;
        ret = avcodec_decode_audio4(Dec_AvContext, pCacheFrame, &got_picture, packet);//解码
        if ( ret < 0 )
        {
         int a= 0;
        }

        if ( got_picture > 0 )
        {
            memset(out_buffer, 0 , out_buffer_size * 2);

            swr_convert(au_convert_ctx,&out_buffer, out_buffer_size,(const uint8_t **)pCacheFrame->data , pCacheFrame->nb_samples);

            // if(outfile)
               // fwrite(out_buffer, 1, out_buffer_size, outfile);

            if(m_pHandler)
                m_pHandler->receive_handler((char*)out_buffer,out_buffer_size);//解码完成发送至播放

        }else
        {

        }
     }

     delete packet;

     return 0;
}

